package com.yuye.java.redis.template;

import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoUnit;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

/**
 *
 * redis热点数据接口
 *
 * @author gzs
 * @version C10 2021年08月05日
 */
public interface RedisHotspotData {

    /**
     *
     * 分布式锁的简单应用
     *
     * @author gzs
     * @param key 分佈式鎖 的key
     * @param value 分佈式鎖 的value
     * @return Boolean true加锁成功 false 加锁失败
     */
     Boolean setnx(String key, String value);

    /**
     * jedis 删除指定标识
     * @param key 处理的redis key
     * @return Long 返回值
     */
    Long del(String key);

    Boolean mset(String... content);

    List<String> mget(String... keys);

    Boolean msetnx(String... content);

    Long strlen(String key);

    String getRange(String key, int startOffset, int endOffset);

    /**
     * 拼接字符串
     * 应用场景：
     *   可实现审计日志的记录
     *
     * @author gzs
     * @param key 键
     * @param value 值
     * @return Boolean true添加成功 false 添加失败
     */
    Boolean append(String key, String value);

    /**
     * key的value 添加1
     * 可能问题：
     *    key是已经存在的
     *    redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
     *
     * @author gzs
     * @param key 键
     * @return Long类型 增加后的value
     */
    Long incr(String key);

    Long incrBy(String key, Long incr);

    Long decr(String key);

    Long hset(String key, String field, String value);

    Long hincrBy(String key, String field, Long value);

    String hget(String key, String field);

    /**
     *
     * 获取hash数据结构下 value的值
     *
     * @author gzs
     * @param key 要获取的key
     * @return Map value值
     */
    Map<String, String> hgetAll(String key);

    String get(String key);

    /**
     * 防止 缓存穿透的 查询  会预留一个空值 防止 多次查询
     * @param key 缓存查询的key
     * @return 有值 就直接返回 没有就返回空值
     */
    String getForPierceThrough(String key);

    String set(String key, String field);

    String set(String key,int senconds, String field);

    /**
     *
     * 执行数据库的操作
     * 例如：
     *    insert
     *    update
     *
     * @author gzs
     * @param key 键
     * @param params map
     * @param f Function
     * @return Object
     */
    Object executeDataBaseHandle(String key,Map<String, Object> params, Function<Map<String, Object>, Object> f);

    /**
     *
     * 从左边放数据 list数据结构
     *
     * @author gzs
     * @param key key值
     * @param value 要存的string 数组对象
     * @return Long 成功多少条
     */
    Long lpush(String key, String... value);

    /**
     *
     * 从右边弹出数据 list数据结构
     *
     * @author gzs
     * @param key 要获取的key值
     * @return String 返回的value
     */
    String rpop(String key);

    Long zadd(String key, Double score,  String member);

    /**
     *
     * zscore 获取当前value的分数
     *
     * @author gzs
     * @param key redis的sort set key
     * @param member 要查询的 value
     * @return Double 当前value的分数
     */
    Double zscore(String key,  String member);

    /**
     *
     * zrem sort set 删除操作
     *
     * @author gzs
     * @param key redis的sort set key
     * @param member 要删除的value 集合
     * @return Long 被成功移除的成员的数量
     */
    Long zrem(String key,  String... member);

    /**
     *
     * zincrby 分数修改
     *
     * @author gzs
     * @param key redis的sort set key
     * @param score 要修改的分数
     * @param member 要处理的value 集合
     * @return Double 修改之后的分数
     */
    Double zincrby(String key,  Double score, String member);

    /**
     *
     * 获取排名 默认从0开始
     *
     * @author gzs
     * @param key redis的sort set key
     * @param member 要处理的value
     * @return Long 当前该条的排名
     */
    Long zrevrank(String key,  String member);

    /**
     *
     * zrevrange 分页获取排行榜
     *
     * @author gzs
     * @param key redis的sort set key
     * @param start 分页的开始
     * @param stop  分页的结束
     * @return 返回的分页数据
     */
    Set<String> zrevrange(String key, long start, long stop);

    /**
     *
     * 应用例子：基于位图的网站用户行为 记录
     *
     * @author gzs
     * @param key setbit的 key 一般根据业务设置
     * @param offset 偏移量 可以是用户id 或者id
     * @param value 设置的通用值 默认是 字符串的1
     * @return Boolean true 是 设置 成功 false 是 设置失败
     */
    Boolean setbit(String key,  long offset, String value);

    /**
     *
     * getbit 获取 是否存在过
     *
     * @author gzs
     * @param key getbit的 key 一般根据业务设置
     * @param offset  偏移量 可以是用户id 或者id
     * @return Boolean true 是 存在 false 是 不存在该数据
     */
    Boolean getbit(String key,  long offset);

    Long geoadd( String key,  Map<String, GeoCoordinate> memberCoordinateMap);

    Double geodist( String key,  String member1,  String member2,  GeoUnit unit);

}
